package com.ordertracker.dao;

import com.ordertracker.persistent.dictionary.ClientEmployee;
import com.ordertracker.persistent.dictionary.template.StateEntityTemplate;
import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Description of class.
 * Created 1/8/13 1:39 PM
 *
 * @author andrey.rodin@playtech.com
 */

public class GeneralCrudDao<T, ID extends Serializable> {

    private SessionFactory sessionFactory;

    @Resource
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Transactional
    @SuppressWarnings("unchecked")
    public T saveEntity(T objToSave) {
        Long id = (Long) sessionFactory.getCurrentSession().save(objToSave);
        return (T) sessionFactory.getCurrentSession().get(objToSave.getClass(), id);
    }

    @Transactional(readOnly = true)
    @SuppressWarnings("unchecked")
    public T findById(ID id, Class<T> objectClass) {
        return (T) sessionFactory.getCurrentSession().get(objectClass, id);
    }

    @Transactional(readOnly = true)
    @SuppressWarnings("unchecked")
    public List<T> getAll(Class<T> objectClass) {
        Criteria criteria = sessionFactory.getCurrentSession().createCriteria(objectClass);
        return (List<T>) criteria.list();
    }

    @Transactional(readOnly = true)
    @SuppressWarnings("unchecked")
    public T findEqualByCriteria(Map<String,String> args, Class<T> objectClass) {
        Criteria criteria = sessionFactory.getCurrentSession().createCriteria(objectClass);
        for (Map.Entry<String, String> entry : args.entrySet()) {
            criteria.add(Restrictions.eq(entry.getKey(),entry.getValue()));
        }
        return (T) criteria.uniqueResult();
    }

    @Transactional(readOnly = true)
    @SuppressWarnings("unchecked")
    public T findEqualByCriteria(String param, Object val, Class<T> objectClass) {
        Criteria criteria = sessionFactory.getCurrentSession().createCriteria(objectClass);
        criteria.add(Restrictions.eq(param, val));
        return (T) criteria.uniqueResult();
    }

    @Transactional(readOnly = true)
    @SuppressWarnings("unchecked")
    public List<T> getAllByCriteria(String param, Object val, Class<T> objectClass) {
        Criteria criteria = sessionFactory.getCurrentSession().createCriteria(objectClass);
        criteria.add(Restrictions.eq(param, val));
        return (List<T>) criteria.list();
    }
    
    @Transactional(readOnly = true)
    @SuppressWarnings("unchecked")
    public List<T> getAllByCriteria(Map<String,Object> args, Class<T> objectClass) {
        Criteria criteria = sessionFactory.getCurrentSession().createCriteria(objectClass);
        for (Map.Entry<String, Object> entry : args.entrySet()) {
            criteria.add(Restrictions.eq(entry.getKey(),entry.getValue()));
        }
        
        return (List<T>) criteria.list();
    }    
}
